package com.hjx.movie.core.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.cache.Cache;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * <p>Title:</p>
 * <p>Description:</p>
 *
 * @author hjx
 * @date 2021/1/2 - 23:34
 */
@Slf4j
public class MybatisCacheRedisMap implements Cache {
    private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    private final String id; // 在构造函数自动注入，为namespace的名字
    private RedisTemplate<String,Object> redisTemplate;
    private HashOperations<String,Object,Object> opsForHash;
    private static final long EXPIRE_TIME_IN_MINUTES = 30; // redis过期时间
    public MybatisCacheRedisMap(String id) {
        if (id == null) {
            throw new IllegalArgumentException("Cache instances require an ID");
        }
        this.id = id;
        log.debug("创建了mybatis的redis缓存"+id);
    }
    @Override
    public String getId() {
        return id;
    }
    /**
     * Put query result to redis
     *
     * @param key
     * @param value
     */
    @Override
    public void putObject(Object key, Object value) {
        this.redisTemplate = getRedisTemplate();
        opsForHash=redisTemplate.opsForHash();
        opsForHash.put(id,key.toString(),value);
        log.debug("redis cache "+id+" put key: "+key.toString()+" value: "+value.toString());
    }
    /**
     * Get cached query result from redis
     *
     * @param key
     * @return
     */
    @Override
    public Object getObject(Object key) {
        this.redisTemplate = getRedisTemplate();
        opsForHash=redisTemplate.opsForHash();
        log.debug("redis cache "+id+" get key: "+key.toString());
        return opsForHash.get(id, key.toString());
    }
    /**
     * Remove cached query result from redis
     *
     * @param key
     * @return
     */
    @Override
    public Object removeObject(Object key) {
        this.redisTemplate = getRedisTemplate();
        log.debug("redis cache "+id+" remove key: "+key.toString());
        opsForHash=redisTemplate.opsForHash();
        opsForHash.delete(id, key.toString());
        return null;
    }
    /**
     * Clears this cache instance
     */
    @Override
    public void clear() {
        this.redisTemplate = getRedisTemplate();
        this.redisTemplate.execute((RedisCallback<Object>) connection -> {
            redisTemplate.delete(id);
            return null;
        });
        log.debug("Clear all the cached query result from redis "+id);
    }
    @Override
    public int getSize() {
        return 0;
    }
    @Override
    public ReadWriteLock getReadWriteLock() {
        return readWriteLock;
    }
    private RedisTemplate<String,Object> getRedisTemplate() {
        if (redisTemplate == null) {
            redisTemplate = ApplicationContextHolder.getBean("redisTemplate");
        }
        return redisTemplate;
    }

}
